﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.Management;
using System.Collections;
// namespaces necesarios para conexión a bd
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Data.SqlTypes;

using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace Persistencia_y_capa_de_negocio
{
    public class CADAdmin
    {
        private static readonly CADAdmin instancia = new CADAdmin();
        public static CADAdmin Instancia
        {
            get { return instancia; }
        }

        private string cadCon;  // Cadena de conexión conseguida desde app.config
        private SqlDataAdapter da;
        private SqlConnection c;
        private DataSet vdb;

        public CADAdmin()
        {
            try
            {
                cadCon = ConfigurationManager.ConnectionStrings["conexion"].ConnectionString;

                vdb = new DataSet();
                c = new SqlConnection(cadCon);
                da = new SqlDataAdapter("SELECT * from admin", c);

                da.Fill(vdb, "admin");    // Ahora tenemos todo el contenido de admins en local.
            }
            catch
            {
                MessageBox.Show("Error en la base de datos");
            }
            
        }

        /// <summary>
        /// Devuelve un ENAdmin de la base de datos, proporcionando el nombre.
        /// </summary>
        /// <param name="usuario"></param>
        /// <returns></returns>
        public ENAdmin DevolverAdmin(string usuario)
        {
            ENAdmin admin = new ENAdmin();


            DataTable t = new DataTable();
            DataRow dr = null;

            t = vdb.Tables["admin"];
            string select = "cuenta = \'" + usuario + "\'";
            try
            {
                dr = t.Select(select)[0];
            }
            catch (Exception)
            {
                return null;
            }
            admin.CuentaAd = dr["cuenta"].ToString().Trim();
            admin.ContrasenaAd = dr["contrasena"].ToString().Trim();
            admin.Nivel = Convert.ToInt32(dr["nivel"].ToString().Trim());
            admin.FechaReg = Convert.ToDateTime(dr["fecharegistro"]);
            return admin;
        }

        /// <summary>
        /// Devuelve el nombre del último administrador registrado de nivel "nivel".
        /// </summary>
        /// <param name="nivel">Nivel del administrador.</param>
        /// <returns>Devuelve el nombre del administrdor.</returns>
        public string getUltimo(int nivel)
        {
            DataTable t = new DataTable();
            DataRow dr = null;

            t = vdb.Tables["admin"];
            string select = "nivel = \'" + nivel + "\'";
            try
            {
                dr = t.Select(select)[0];
            }
            catch (Exception)
            {
                return null;
            }
            return dr["cuenta"].ToString().Trim();
        }

        /// <summary>
        /// Inserta un ENAdmin en la base de datos
        /// </summary>
        /// <param name="ad"></param>
        /// <returns></returns>
        public bool InsertarAdmin(ENAdmin ad)
        {
            DataTable t = new DataTable();

            t = vdb.Tables["admin"];
            // Ahora tengo la tabla admin.

            bool insertado = false;

            DataRow r = null;

            string select = "cuenta = \'" + ad.CuentaAd + "\'";
            try
            {
                r = t.Select(select)[0];

                r["cuenta"] = ad.CuentaAd.ToString();
                r["contrasena"] = ad.ContrasenaAd.ToString();
                r["nivel"] = ad.Nivel;
                r["fecharegistro"] = ad.FechaReg;
                
                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "admin");
            }
            catch
            {
                r = t.NewRow();

                r["cuenta"] = ad.CuentaAd.ToString();
                r["contrasena"] = ad.ContrasenaAd.ToString();
                r["nivel"] = ad.Nivel;
                r["fecharegistro"] = ad.FechaReg;
                // Añadimos la nueva fila a la tabla virtual.
                t.Rows.Add(r);

                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "admin");

                insertado = true;
            }
            return insertado;
        }

        /// <summary>
        /// Devuelve un arrayList con todos los admins en la base de datos
        /// </summary>
        /// <returns></returns>
        public ArrayList getAdmins()
        {
            ArrayList lista = new ArrayList();

            try
            {

                DataTable t = new DataTable();
                t = vdb.Tables["admin"];

                foreach (DataRow r in t.Rows)
                {
                    ENAdmin ad = new ENAdmin();

                    // Insertamos los datos en el nuevo edificio.
                    ad.CuentaAd = r["cuenta"].ToString().Trim();
                    ad.ContrasenaAd = r["contrasena"].ToString().Trim();
                    ad.Nivel = Convert.ToInt32(r["nivel"].ToString().Trim());
                    ad.FechaReg = Convert.ToDateTime(r["fecharegistro"]);
                    lista.Add(ad);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            
            return lista;
        }

        /// <summary>
        /// Devuelve el numero de administradores del nivel indicado.
        /// </summary>
        /// <param name="nivel">Nivel del que se desea obtener el número de admins.</param>
        /// <returns>Devuelve la cantidad de administradores de ese nivel.</returns>
        public int getNumAdmins(int nivel)
        {
            DataTable t = new DataTable();
            t = vdb.Tables["admin"];
            string select = "nivel = \'" + nivel + "\'";
            try
            {
                return t.Select(select).Count();
            }
            catch (Exception)
            {
                return 0;
            }
        }

        /// <summary>
        /// Modifica la información de la base de datos para ese admin
        /// </summary>
        /// <param name="ad"></param>
        /// <returns></returns>
        public bool ModificarAdmin(ENAdmin ad)
        {
            DataTable t = new DataTable();

            t = vdb.Tables["admin"];
            // Ahora tengo la tabla admin.
            DataRow r = null;

            bool modificado = false;

            string select = "cuenta = \'" + ad.CuentaAd + "\'";


            try
            {
                // Si no lanza la excepción significa que hay que modificar.
                r = t.Select(select)[0];
                r["nivel"] = ad.Nivel.ToString();
                r["contrasena"] = ad.ContrasenaAd.ToString();

                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "admin");
                modificado = true;


            }
            catch (Exception)
            {
                //Mostramos errorcete
                modificado = false;
            }

            return modificado;
        }

        /// <summary>
        /// Elimina de la base de datos un administrador
        /// </summary>
        /// <param name="nombre"></param>
        public void EliminaAdmin(string nombre)
        {
            string select = "cuenta = \'" + nombre + "\'";

            DataTable t = vdb.Tables["admin"];

            try
            {
                DataRow r = t.Select(select)[0];
                r.Delete();

                SqlCommandBuilder command = new SqlCommandBuilder(da);

                // Actualizamos los cambios en la BD real.
                da.Update(vdb, "admin");
            }
            catch
            {
                // Soltamos algún errorcete.
            }
        }
    }
}
